package com.ebelter.seneo.models.googlefit;

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.FitnessOptions;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

import java.util.concurrent.TimeUnit;

import static com.google.android.gms.auth.api.signin.GoogleSignIn.getSignedInAccountFromIntent;
import static com.google.android.gms.auth.api.signin.internal.zzh.getSignInResultFromIntent;


public class UtilGoogleFitt {

    private static final String TAG = "UtilGoogleFitt";
    public static final int GOOGLE_SIGN_IN = 101;
    public static final int GOOGLE_FIT_PERMISSIONS_REQUEST_CODE = 121;

    private Activity mActivity;

    private GoogleSignInAccount signInAccount;

    public UtilGoogleFitt(Activity activity) {
        mActivity = activity;
    }

    /**
     * 需要上传的数据选项
     */
    public FitnessOptions fitnessOptions = FitnessOptions.builder()
            //步数
            .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_WRITE)
            //距离
            .addDataType(DataType.TYPE_DISTANCE_DELTA, FitnessOptions.ACCESS_WRITE)
            .build();

    /**
     * 获取谷歌账号
     */
    public void getGoogleSignIn() {
        //如果已经登录过google账号。则可以拿到账号
        signInAccount = GoogleSignIn.getLastSignedInAccount(mActivity);
        if (signInAccount == null) {
            Log.i(TAG, "没有登录");
            //没有。则要登录
            signIn(UtilGoogleFitt.GOOGLE_SIGN_IN);
        } else {
            Log.i(TAG, "有，则要订阅");
            //有，则要订阅
            sunbscrerib();
        }
    }


    /**
     * 登录
     *
     * @param google_sign_in 回调的Code
     */
    public void signIn(int google_sign_in) {
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build();
        GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(mActivity, gso);
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        mActivity.startActivityForResult(signInIntent, google_sign_in);
    }


    /**
     * 在activity的onActivityResult方法里面调用，回调是否登录账号成功。
     *
     * @param data
     */
    public void handleSignInResult(int requestCode, Intent data) {
        Log.i(TAG, "登录的回调 requestCode = " + requestCode + "  data = " + data.getData());
        if (requestCode != GOOGLE_SIGN_IN) {
            return;
        }
        try {
            GoogleSignInResult result = getSignInResultFromIntent(data);
            Log.i(TAG, "登录的回调 result = " + result.isSuccess());
            if (result.isSuccess()) {
                signInAccount = getSignedInAccountFromIntent(data).getResult(ApiException.class);
                sunbscrerib();
            }
        } catch (ApiException e) {
            Log.i(TAG, "登录错误 = " + e.getMessage());
        }
    }


    /**
     * 订阅
     */
    public void sunbscrerib() {
        signInAccount = GoogleSignIn.getLastSignedInAccount(mActivity);
        if (signInAccount == null) {
            return;
        }
        //判断是否有写入数据的权限，这个会弹出授权写入数据的弹框
        if (!GoogleSignIn.hasPermissions(signInAccount, fitnessOptions)) {
            Log.i(TAG, "订阅有权限");
            GoogleSignIn.requestPermissions(
                    mActivity, // your activity
                    GOOGLE_FIT_PERMISSIONS_REQUEST_CODE,
                    signInAccount,
                    fitnessOptions);
        } else {
            Log.i(TAG, "订阅没有权限");
            subscriptionData();
        }
    }


    public void subscriptionData() {
        subscribe(DataType.TYPE_STEP_COUNT_DELTA);// 订阅步数
        subscribe(DataType.TYPE_DISTANCE_DELTA);// 订阅距离
    }

    // 订阅
    public void subscribe(final DataType dataType) {
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(mActivity);
        if (account == null) {
            return;
        }
        Fitness.getRecordingClient(mActivity, GoogleSignIn.getLastSignedInAccount(mActivity))
                .subscribe(dataType)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        //每订阅成功一个，会回调这个方法
                        Log.i(TAG, "订阅成功一个");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.i(TAG, "订阅失败一个");
                    }
                });
    }


    /**
     * 创建要上传的数据对象
     *
     * @param dataType  DataType类型
     * @param field     Field类型
     * @param values    数据值
     * @param startTime 开始时间戳
     * @param endTime   结束时间戳
     * @return 开始时间戳必须小于结束时间戳，不然就抛异常
     */
    public DataSet createDataForRequest(DataType dataType, Field field, Object values, long startTime, long endTime) {
        DataSource dataSource;
        DataSet dataSet = null;
        dataSource =
                new DataSource.Builder()
                        .setAppPackageName(mActivity)
                        .setDataType(dataType)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        dataSet = DataSet.create(dataSource);
        DataPoint dataPoint =
                dataSet.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
        try {
//            if (dataType == DataType.TYPE_CALORIES_EXPENDED || dataType == DataType.TYPE_HEART_RATE_BPM) {
//                dataPoint.getValue(field).setInt(values);
//            } else {
            //如果是float类型则要调用setFloagValues
            if (values instanceof Integer) {
                dataPoint.setIntValues((int) values);
            } else {
                dataPoint.setFloatValues((float) values);
            }
//            }
            dataSet.add(dataPoint);
        } catch (Exception e) {
            Log.i(TAG, "报错了 = " + e.getMessage());
        }
        return dataSet;
    }


    /**
     * 开始上传数据
     */
    public void startData(final DataSet stepDataSet, final DataSet distanceDataSet) {
        if (signInAccount == null) {
            Log.i(TAG, "请先登录");
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                Task<Void> responseStep = Fitness.getHistoryClient(mActivity, GoogleSignIn.getLastSignedInAccount(mActivity)).insertData(stepDataSet);
                Task<Void> responseDistance = Fitness.getHistoryClient(mActivity, GoogleSignIn.getLastSignedInAccount(mActivity)).insertData(distanceDataSet);


                // 等待任务完成
                while (!responseStep.isComplete() && !responseDistance.isCanceled()) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Log.i(TAG, "数据上传完成");
            }
        }).start();
    }
}
